#include "zf_device_uvc.h"


#include <opencv2/imgproc/imgproc.hpp>  // for cv::cvtColor
#include <opencv2/highgui/highgui.hpp> // for cv::VideoCapture
#include <opencv2/opencv.hpp>

#include <iostream> // for std::cerr
#include <fstream>  // for std::ofstream
#include <iostream>
#include <opencv2/opencv.hpp>
#include <thread>
#include <chrono>
#include <atomic>

#include <vector> // 添加vector头文件
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std; // 确保使用std命名空间
using namespace cv;

cv::Mat frame_rgb;      // 构建opencv对象 彩色
cv::Mat frame_rgay;     // 构建opencv对象 灰度

uint8_t *rgay_image;    // 灰度图像数组指针

VideoCapture cap;

int8 uvc_camera_init(const char *path)
{
    cap.open(path);

    if(!cap.isOpened())
    {
        printf("find uvc camera error.\r\n");
        return -1;
    } 
    else 
    {
        printf("find uvc camera Successfully.\r\n");
    }
    bool fourccSet = cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M','J','P','G'));
    if (!fourccSet) {
        std::cerr << "警告：无法设置MJPEG格式，可能不支持该编码" << std::endl;
    }
    cap.set(CAP_PROP_FRAME_WIDTH, 160);     // 设置摄像头宽度
    cap.set(CAP_PROP_FRAME_HEIGHT, 120);    // 设置摄像头高度
    cap.set(CAP_PROP_FPS, UVC_FPS);              // 显示屏幕帧率
    // 设置曝光参数
    // 1. 关闭自动曝光（部分摄像头需设置特定值，3 自动曝光 1 关闭自动曝光）
    // cap.set(cv::CAP_PROP_AUTO_EXPOSURE, 1);
    // 2. 设置手动曝光值（具体范围需参考摄像头规格）
    // bool exposureSuccess = cap.set(cv::CAP_PROP_EXPOSURE, 15);
    // if (!exposureSuccess)
    // {
    //     printf("Warning: Failed to set exposure value. Check camera support.\r\n");
    // }
    // else
    // {
    //     double actualExposure = cap.get(cv::CAP_PROP_EXPOSURE);
    //     printf("Exposure set to: %.2f\r\n", actualExposure);
    // }
    return 0;
}
// 参数配置
double contrast = 1;   // 对比度系数 (>1增强 <1减弱)
int brightness =-20;     // 亮度增量 (正值增亮，负值变暗)
int VALUE_Key=0;
int threshold_value = 128;    // 阈值（0-255）
int frame_count = 0;
auto start_time = std::chrono::steady_clock::now();
double fps = 0;
int8 wait_image_refresh()
{
    try 
    {
        // 阻塞式等待图像刷新
        cap >> frame_rgb;
        // cap.read(frame_rgb);
        if (frame_rgb.empty()) 
        {
            std::cerr << "未获取到有效图像帧" << std::endl;
            return -1;
        }
    } 
    catch (const cv::Exception& e) 
    {
        std::cerr << "OpenCV 异常: " << e.what() << std::endl;
        return -1;
    }
    // double actualExposure = cap.get(cv::CAP_PROP_EXPOSURE);
    // printf("Exposure set to: %.2f\r\n", actualExposure);
    // 计算帧率
    frame_count++;
    auto end_time = std::chrono::steady_clock::now();
    double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>
                        (end_time - start_time).count() / 1000.0;
        
    if (elapsed >= 1.0) { // 每1秒更新一次
        fps = frame_count / elapsed;
        frame_count = 0;
        start_time = end_time;
    }
    
    cv::Rect roi(5, 10, 155, 70); // 格式: Rect(x, y, width, height)

    // 执行裁剪
    cv::Mat cropped_img = frame_rgb(roi).clone(); // 使用clone()确保独立内存
    
    //压缩图像
    // 目标尺寸（注意 OpenCV 使用 width-first 顺序）
    Size targetSize(155, 70);
    resize(cropped_img, frame_rgb, targetSize, 0, 0, INTER_AREA);

    // rgb转灰度
    cv::cvtColor(frame_rgb, frame_rgay, cv::COLOR_BGR2GRAY);

    // ====== 新增：对比度和亮度调整 ======
    try {
        // 高效调整：g(x) = contrast * x + brightness
        frame_rgay.convertTo(frame_rgay, -1, contrast, brightness);
        
        // 像素值裁剪到[0,255]范围
        cv::threshold(frame_rgay, frame_rgay, 255, 255, cv::THRESH_TRUNC);
        cv::threshold(frame_rgay, frame_rgay, 0, 0, cv::THRESH_TOZERO);
    } 
    catch (const cv::Exception& e) {
        std::cerr << "亮度/对比度调整失败: " << e.what() << std::endl;
        return -1;
    }
    // ====== 调整结束 ======
    //设置二值化是否使用固定阈值
    if(VALUE_Key==1)
    {
        try {
        // const int threshold_value = 128;    // 阈值（0-255）
        const int max_binary_value = 255;   // 最大值
        
        // 固定阈值二值化
        cv::threshold(
            frame_rgay,            // 输入图像（高斯模糊后的灰度图）
            frame_rgay,            // 输出图像（原地处理）
            threshold_value,       // 阈值
            max_binary_value,     // 最大值
            cv::THRESH_BINARY      // 二值化类型
        );
    } 
    catch (const cv::Exception& e) 
    {
        std::cerr << "二值化处理失败: " << e.what() << std::endl;
        return -1;
    }
    }
    else//大津法
    {
        try { 
        //可选自适应阈值方法（Otsu算法）
        cv::threshold(
            frame_rgay,
            frame_rgay,
            0,                    // 自动计算阈值时设为0
            255,
            cv::THRESH_BINARY | cv::THRESH_OTSU
        );
    } 
    catch (const cv::Exception& e) 
    {
        std::cerr << "二值化处理失败: " << e.what() << std::endl;
        return -1;
    }
    }
    //形态学降噪
    int kernel_size = 3;  // 核大小（推荐3-5，噪声大时可增大）
    Mat kernel = getStructuringElement(
        MORPH_ELLIPSE,    // 核形状：MORPH_RECT矩形/MORPH_ELLIPSE椭圆
        Size(kernel_size, kernel_size)
    );
    morphologyEx(frame_rgay, frame_rgay, MORPH_OPEN, kernel);
    morphologyEx(frame_rgay, frame_rgay, MORPH_CLOSE, kernel);

    // cv对象转指针
    rgay_image = reinterpret_cast<uint8_t *>(frame_rgay.ptr(0));

    return 0;
}
//颜色识别
int ShiBie_YanSe(int Color)
{
    Mat hsv;
    cvtColor(frame_rgb, hsv, COLOR_BGR2HSV);
    //黑色
    Scalar lower_black = Scalar(0, 0, 0);
    Scalar upper_black = Scalar(180, 255, 40); // 调整第三个值控制黑色敏感度
    //白色
    Scalar lower_white = Scalar(0, 0, 200);    // H最小值, S最小值, V最小值
    Scalar upper_white = Scalar(180, 30, 255); // H最大值, S最大值, V最大值
    //红色
    Scalar lower_red = Scalar(156, 43, 46);    // H最小值, S最小值, V最小值
    Scalar upper_red = Scalar(180, 255, 255); // H最大值, S最大值, V最大值
    //绿色
    Scalar lower_green = Scalar(78, 43, 46);    // H最小值, S最小值, V最小值
    Scalar upper_green = Scalar(99, 255, 255); // H最大值, S最大值, V最大值

    Mat mask;
    if(Color==1)
    {
        // 颜色阈值处理
        inRange(hsv, lower_black, upper_black, mask);
    }
    else if(Color==2)
    {
        // 颜色阈值处理
        inRange(hsv, lower_white, upper_white, mask);
    }
    else if(Color==3)
    {
        // 颜色阈值处理
        inRange(hsv, lower_green, upper_green, mask);
    }
    else if(Color==4)
    {
        // 颜色阈值处理
        inRange(hsv, lower_red, upper_red, mask);
    }
    // 形态学操作（去噪）
    Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));
    morphologyEx(mask, mask, MORPH_OPEN, kernel);  // 去除白噪声
    morphologyEx(mask, mask, MORPH_CLOSE, kernel); // 填充黑孔洞

    // 查找轮廓
    std::vector<std::vector<Point> > contours;
    findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    for (size_t i = 0; i < contours.size(); i++) 
    {
        // 计算轮廓面积
        double area = contourArea(contours[i]);
        //不同的颜色有不同的阈值
        if(Color==1)
        {
            if (area > 1000)
            {
                return 1;
            }
        }
        else if(Color==2)
        {
            if (area > 1000)
            {
                return 1;
            }
        }
        else if(Color==3)
        {
            if (area > 1000)
            {
                return 1;
            }
        }
        else if(Color==4)
        {
            if (area > 1000)
            {
                return 1;
            }
        }
    }
    return 0;
}


